package com.aivin.maproutelib.tool;

import com.aivin.maproutelib.bean.WaypointInfo;
import com.aivin.maproutelib.line.ScanLine;
import com.aivin.maproutelib.line.HelperLine;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.model.LatLng;

import java.util.List;
import java.util.Locale;

public class MapTool {

    private static float calculateLineDistance(LatLng latlng, LatLng latlng1) {
        return AMapUtils.calculateLineDistance(new LatLng(latlng.latitude, latlng.longitude), new LatLng(latlng1.latitude, latlng1.longitude));
    }

    /**
     * 计算距离
     */
    public static String getDistanceStr(LatLng fLL, LatLng toLL) {
        float lineDistance = calculateLineDistance(fLL, toLL);
        if (lineDistance > 1000) {
            return String.format(Locale.CHINA,"%.1f", lineDistance / 1000f) + " km";
        }
        return String.format(Locale.CHINA,"%.1f", lineDistance) + " m";
    }



    /**
     * 计算两个点之间的距离
     */
    public static double calculationTwoPointDistance(WaypointInfo point, WaypointInfo point1) {
        double v = (point.getLatitude() - point1.getLatitude()) * (point.getLatitude() - point1.getLatitude()) + (point.getLongitude() - point1.getLongitude()) * (point.getLongitude() - point1.getLongitude());
        return Math.sqrt(v);
    }


    /**
     * 计算整条航线的路程
     */
    public static double sumDistance(List<WaypointInfo> points) {
        double sum = 0;
        for (int i = 0; i < points.size() - 1; i++) {
            WaypointInfo waypointInfo = points.get(i);
            WaypointInfo next;
            next = points.get(i + 1);
            double distance = calculationTwoPointDistance(waypointInfo, next);
            sum += distance;
        }
        return sum;
    }

    /**
     * 根据经纬度 求得实际距离
     * @return xx 米
     */
    public static double getDistance(LatLng start, LatLng end) {
        // 弧度= 度* Math.PI/180
        double lat1 = (Math.PI / 180) * start.latitude;
        double lat2 = (Math.PI / 180) * end.latitude;

        double lon1 = (Math.PI / 180) * start.longitude;
        double lon2 = (Math.PI / 180) * end.longitude;
        //地球半径 6371.004 km  
        double R = 6371;
        //两点间距离 km，
        // D = arc cos(   (sin纬A×sin纬B) ＋  (cos纬A×cos纬B×cosAB两地经度差)) ×地球平均半径 ，此公式固定
        double d = Math.acos(   Math.sin(lat1) * Math.sin(lat2)   +    Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1)  ) * R;
        return d * 1000;
    }

    /**
     * 获取点到直线的距离
     */
    public static double getPointToLineDistance(WaypointInfo point, ScanLine scanLine) {
        // d=|kx0-y0+b|/根号(k²+1)
        return Math.abs( scanLine.k * point.getLatitude() - point.getLongitude() + scanLine.b)
                / Math.sqrt(scanLine.k * scanLine.k + 1);
    }


    /**
     * 获取 2条线段的交点
     */
    public static WaypointInfo getIntersectionPoint(ScanLine line ,ScanLine line2) {
        double v = line2.k - line.k;
        if (v == 0) {
            //表示平行
            return null;
        }
        double x = ((line.b - line2.b) / v);
        if (line.isInXRange(x) && line2.isInXRange(x)) {
            double y = line.getY(x);
            return new WaypointInfo(x, y   );
        } else {//不在线段上
            return null;
        }
    }

    /**
     * 获取与2个线段的交点
     */
    public static WaypointInfo  getIntersectionPoint(HelperLine line , ScanLine line2) {
        double v = line2.k - line.k ;
        if (v == 0) {
            //表示平行
            return null;
        }
        double x = ((line.b - line2.b) / v);
        if (line.isInXRange(x) && line2.isInXRange(x)) {
            double y = line.getY(x);
            return new WaypointInfo(x, y   );
        } else {//不在线段上
            return null;
        }
    }

    /**
     * 判断一个点是否在线段上
     */
    public static boolean isOnLine(WaypointInfo point , HelperLine line) {
        double y2 = line.getY(point.getLatitude());
        double y1 = point.getLongitude();
        return line.isInXRange( point.getLatitude()) &&    Math.abs( y2  - y1 ) < 0.000000001;
    }


    public static LatLng createLatlng(double lat, double lon) {
        return new LatLng(lat,lon);
    }

}
